namespace Xsxiaosa.Net
{
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
// jyj add	
	using System.Text;


    internal class ProxyHttpConnect : ProxyBase
    {
        // Methods
        public ProxyHttpConnect(Socket socket) : base(socket)
        {
            this.r = new byte[16];
        }

        public override IAsyncResult BeginAccept(AsyncCallback callback, object state)
        {
            throw new NotSupportedException(Messages.GetString(typeof(ProxySocketStrings), "HttpNotSupported"));
        }

        public override IAsyncResult BeginConnect(IPEndPoint endPoint, AsyncCallback callback, object state)
        {
            return this.BeginConnect(endPoint.Address.ToString(), endPoint.Port, callback, state);
        }

        public override IAsyncResult BeginConnect(string serverName, int serverPort, AsyncCallback callback, object state)
        {
            byte[] numArray1;
            IPEndPoint point1;
//            IAsyncResult result1;
            object[] objArray1 = new object[9];
            objArray1[0] = "CONNECT ";
            objArray1[1] = serverName;
            objArray1[2] = ":";
            objArray1[3] = serverPort;
            objArray1[4] = " HTTP/1.1\r\nHost: ";
            objArray1[5] = serverName;
            objArray1[6] = ":";
            objArray1[7] = serverPort;
            objArray1[8] = "\r\n";
            this.request = string.Concat(objArray1);
            if ((this._proxyUserName.Length > 0) && (this._proxyPassword.Length > 0))
            {
                numArray1 = Encoding.ASCII.GetBytes(string.Concat(this._proxyUserName, ":", this._proxyPassword));
                this.request = string.Concat(this.request, "Proxy-Authorization: basic ", Convert.ToBase64String(numArray1, 0, numArray1.Length), "\r\n");
            }
            this.request = string.Concat(this.request, "\r\n");
            base.Begin("Connect", callback, state);
            try
            {
                point1 = ProxySocket.ToEndPoint(this._proxyHost, this._proxyPort);
                if (point1 != null)
                {
                    base.Socket.BeginConnect(point1, new AsyncCallback(this.Connect1), null);
                }
                else
                {
                    Dns.BeginGetHostEntry(this._proxyHost, new AsyncCallback(this.Connect0), null);
                }
                return this._asyncResult;
            }
            catch (Exception exception1)
            {
                throw base.CancelBegin(exception1);
            }
//jyj modify
//            return result1;
        }

        public override IAsyncResult BeginListen(ProxyBase controlSocket, AsyncCallback callback, object state)
        {
            throw new NotSupportedException(Messages.GetString(typeof(ProxySocketStrings), "HttpNotSupported"));
        }

        private void Connect0(IAsyncResult result)
        {
            IPHostEntry entry1;
            IPEndPoint point1;
            try
            {
                try
                {
                    entry1 = Dns.EndResolve(result);
                }
                catch (SocketException exception1)
                {
                    base.SetError(new ProxySocketException(Messages.GetString(typeof(ProxySocketStrings), "ResolveFailed"), ProxySocketExceptionStatus.ProxyNameResolutionFailure, exception1));
                    base.Finish();
                    return;
                }
                point1 = new IPEndPoint(entry1.AddressList[0], this._proxyPort);
                base.Socket.BeginConnect(point1, new AsyncCallback(this.Connect1), null);
            }
            catch (Exception exception2)
            {
                base.SetError(exception2);
                base.Finish();
            }
        }

        private void Connect1(IAsyncResult result)
        {
            byte[] numArray1;
            try
            {
                base.Socket.EndConnect(result);
            }
            catch (Exception exception1)
            {
                base.SetError(new ProxySocketException(exception1.Message, ProxySocketExceptionStatus.ConnectFailure, exception1));
                base.Finish();
                return;
            }
            try
            {
                numArray1 = Encoding.ASCII.GetBytes(this.request);
                base.Socket.BeginSend(numArray1, 0, numArray1.Length, SocketFlags.None, new AsyncCallback(this.Connect2), null);
            }
            catch (Exception exception2)
            {
                base.SetError(exception2);
                base.Finish();
            }
        }

        private void Connect2(IAsyncResult result)
        {
            int num1;
            string text1;
            MemoryStream stream1;
            try
            {
                if (result.AsyncState == null)
                {
                    base.Socket.EndSend(result);
                    num1 = 0;
                }
                else
                {
                    num1 = ((int) result.AsyncState);
                    num1 += base.Socket.EndReceive(result);
                }
                if (num1 < 12)
                {
                    base.Socket.BeginReceive(this.r, num1, (12 - num1), SocketFlags.None, new AsyncCallback(this.Connect2), num1);
                    return;
                }
                text1 = Encoding.ASCII.GetString(this.r, 0, 12);
                stream1 = new MemoryStream();
                stream1.Write(this.r, 0, 12);
                if (text1.Substring(0, 5) != "HTTP/")
                {
                    throw new ProxySocketException(Messages.GetString(typeof(ProxySocketStrings), "HttpInvalidResponse"), ProxySocketExceptionStatus.ServerProtocolViolation);
                }
                base.Socket.BeginReceive(this.r, 0, 1, SocketFlags.None, new AsyncCallback(this.Connect3), stream1);
            }
            catch (Exception exception1)
            {
                base.SetError(exception1);
                base.Finish();
            }
        }

        private void Connect3(IAsyncResult result)
        {
            int num1;
            MemoryStream stream1;
            byte[] numArray1;
            string text1;
            int num2;
            object[] objArray1;
            try
            {
                num1 = base.Socket.EndReceive(result);
                stream1 = ((MemoryStream) result.AsyncState);
                stream1.Write(this.r, 0, num1);
                if (!base.Socket.Connected)
                {
                    throw new ProxySocketException(Messages.GetString(typeof(ProxySocketStrings), "HttpInvalidResponse"), ProxySocketExceptionStatus.ConnectionClosed);
                }
                numArray1 = stream1.GetBuffer();
                num1 = ((int) stream1.Length);
                if (((numArray1[(num1 - 4)] != 13) || (numArray1[(num1 - 3)] != 10)) || ((numArray1[(num1 - 2)] != 13) || (numArray1[(num1 - 1)] != 10)))
                {
                    base.Socket.BeginReceive(this.r, 0, 1, SocketFlags.None, new AsyncCallback(this.Connect3), stream1);
                    return;
                }
                text1 = Encoding.ASCII.GetString(numArray1, 0, num1);
                num2 = text1.IndexOf("\r\n");
                if (num2 < 13)
                {
                    throw new ProxySocketException(Messages.GetString(typeof(ProxySocketStrings), "HttpInvalidResponse"), ProxySocketExceptionStatus.ServerProtocolViolation);
                }
//jyj modify                if (text1.Chars[9] != '2')
				if (text1[9] != '2')
                {
                    objArray1 = new object[2];
                    objArray1[0] = text1.Substring(13, (num2 - 13)).Trim();
                    objArray1[1] = text1.Substring(9, 3);
                    throw new ProxySocketException(Messages.GetString(typeof(ProxySocketStrings), "HttpError", objArray1), ProxySocketExceptionStatus.ProtocolError);
                }
                stream1.Close();
                base.Finish();
            }
            catch (Exception exception1)
            {
                base.SetError(exception1);
                base.Finish();
            }
        }


        // Fields
        private byte[] r;
        private string request;
    }}

